﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Threading;
using dk2Database;
using dk2Database.Commands;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace dk2Repository.UnitTesting
{
    [TestClass]
    public class RepositoryTests
    {
        private string _tempfile;

        public RepositoryTests()
        {
            try
            {
                ((DataSet)ConfigurationManager.GetSection("system.data")).Tables[0].Rows.Add("SQLite Data Provider", ".Net Framework Data Provider for SQLite", "System.Data.SQLite", "System.Data.SQLite.SQLiteFactory, System.Data.SQLite");
            }
            catch (Exception)
            {
                
            }

            _tempfile = Path.GetTempFileName();
            Databases.RegisterDefault(new SqLiteDatabase(_tempfile, ""));
            User.CreateTableIfNotExists();
            Department.CreateTableIfNotExists();
        }

        ~RepositoryTests()
        {
            Databases.Dispose();

            File.Delete(_tempfile);
        }


        


        [TestMethod]
        public void TestAll()
        {




            var u = new User();

            u.Name = "user1";
            u.Gender = User.enumGender.Male;
            u.DateOfBirth = DateTime.Now;

            u.Insert();

            var id = u.Id;

            Assert.AreEqual(1, id);

            u = User.SelectById(id);
            Assert.AreEqual("user1", u.Name);

            u.Name = "user2";
            u.Gender = User.enumGender.Female;
            u.DateOfBirth = DateTime.Now.AddDays(1);

            Assert.IsTrue(u.Update());

            u = User.SelectById(id);

            Assert.AreEqual("user2", u.Name);


            Assert.IsTrue(u.Delete());

            u = User.SelectById(id);

            Assert.IsNull(u);




            
        }


        [TestMethod]
        public void TestTransaction()
        {
            var u = new User();

            var cmds = new List<ExecuteCommand>();
            for (uint i = 0; i < 10; i++)
            {
                u.Name = "val" + i;
                u.Gender = User.enumGender.Male;
                u.DateOfBirth = DateTime.Now.AddSeconds(i);
                u.DepartmentId = (int)((i % 2) + 1);
                cmds.Add(u.InsertCommand);
            }

            var t = new TransactionInvoker();
            t.AddCommands(cmds);
            t.Execute();
            
            cmds.Clear();
            var l = User.SelectAll();

            foreach (var td1 in l)
                cmds.Add(td1.UpdateCommand);

            t = new TransactionInvoker();
            t.AddCommands(cmds);
            t.Execute();

            var t2 = new CommandInvoker();
            t2.AddCommands(cmds);
            t2.Execute();

            cmds.Clear();

            foreach (var td1 in l)
            {
                cmds.Add(td1.UpdateCommand);
            }

            t = new TransactionInvoker();
            t.AddCommands(cmds);
            t.Execute();


        }

        [TestMethod]
        public void TestRuntime()
        {
            const int items=100000;

            var u = new User();

            var d = new Department();
            d.Name = "dep1";
            d.Insert();
            d.Name = "dep2";
            d.Insert();

            var cmds = new List<ExecuteCommand>();



            for (uint i = 0; i < items; i++)
            {
                u.Name = "val" + i;
                u.Gender = User.enumGender.Male;
                u.DateOfBirth = DateTime.Now.AddSeconds(i);
                u.DepartmentId = (int)((i%2) + 1);
                cmds.Add(u.InsertCommand);
            }

            var stopWatch = new Stopwatch();
            stopWatch.Start();
            TransactionInvoker t = new TransactionInvoker();
            t.AddCommands(cmds);
            t.Execute();
            stopWatch.Stop();
            var ts = stopWatch.Elapsed;
            var elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
            Debug.WriteLine("Transaction Insert (" + items + " Items) RunTime: " + elapsedTime);

            stopWatch.Reset();
            stopWatch.Start();
            var l = User.SelectAll();
            stopWatch.Stop();
            ts = stopWatch.Elapsed;
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
            Debug.WriteLine("FindAll (" + items + " Items) RunTime: " + elapsedTime);


            stopWatch.Reset();
            stopWatch.Start();
            l = User.SelectAll(true);
            stopWatch.Stop();
            ts = stopWatch.Elapsed;
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
            Debug.WriteLine("FindAll Ref (" + items + " Items) RunTime: " + elapsedTime);       

        }
    }
}
